package filesystem

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"
)

// AppendContent2File 在文件后面追加内容
func AppendContent2File(filePath string, content string) (err error) {
	var (
		file *os.File
	)
	if file, err = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644); err != nil {
		return
	}
	defer file.Close()

	_, err = file.WriteString(content + "\n")
	return
}

// CommentFileContent 注释掉文件中所有包含某字符串的内容
func CommentFileContent(filePath string, searchString string, exceptSearchString string) (resultDocs map[int]string, err error) {
	var (
		maxLineNumber int
		docs          map[int]string
	)
	if maxLineNumber, docs, err = FindContentFromLinuxEtcHosts(filePath, searchString, exceptSearchString, false); err != nil ||
		docs == nil || len(docs) == 0 || maxLineNumber <= 0 {
		return
	}
	resultDocs, err = ReplaceFileContentWithComment(filePath, docs, maxLineNumber, false)

	return
}

// UnCommentFileContent 去掉注释（文件中所有包含某字符串的行）
func UnCommentFileContent(filePath string, searchString string, exceptSearchString string) (resultDocs map[int]string, err error) {
	var (
		maxLineNumber int
		docs          map[int]string
	)
	if maxLineNumber, docs, err = FindContentFromLinuxEtcHosts(filePath, searchString, exceptSearchString, true); err != nil ||
		docs == nil || len(docs) == 0 || maxLineNumber <= 0 {
		return
	}
	resultDocs, err = ReplaceFileContentWithComment(filePath, docs, maxLineNumber, true)

	return
}

// ReplaceFileContentWithComment 替换文件内容(加上注释或者去掉)
/*
	isUncomment: 是否去掉注释
*/
func ReplaceFileContentWithComment(filePath string, docs map[int]string, maxLineNumber int,
	isUncomment bool) (resultDocs map[int]string, err error) {
	if maxLineNumber <= 0 {
		err = errors.New(fmt.Sprintf("maxLineNumber is not valid:%d", maxLineNumber))
		return
	}
	var (
		in, out       *os.File
		doneWord      string
		countReplaced int
	)
	if in, err = os.Open(filePath); err != nil {
		return
	}
	defer in.Close()

	if out, err = os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0766); err != nil {
		return
	}
	defer out.Close()

	br := bufio.NewReader(in)
	index := 1
	resultDocs = make(map[int]string, 0)
	if isUncomment {
		doneWord = "去注释"
	} else {
		doneWord = "加注释"
	}
	for index <= maxLineNumber {
		var (
			doc     string
			newDoc  string
			ok      bool
			line    []byte
			newLine string
		)
		doc, ok = docs[index]
		if line, _, err = br.ReadLine(); err == io.EOF {
			break
		}
		if err == nil {
			if ok && doc != "" {
				if isUncomment {
					//去掉注释前缀
					newDoc = strings.TrimPrefix(strings.TrimSpace(doc), "#")
				} else {
					newDoc = "#" + doc
				}
				newLine = strings.Replace(string(line), doc, newDoc, 1)
				if _, err = out.WriteString(newLine + "\n"); err == nil {
					resultDocs[index] = newLine
					countReplaced++
					fmt.Printf("replace %s line:%d\n", doneWord, index)
				}
			} else {
				_, err = out.WriteString(string(line) + "\n")
			}
		}
		if err != nil {
			return
		}
		index++
	}
	fmt.Printf("FINISH replace, countReplaced:%d!\n", countReplaced)
	return
}
